CM3D2 Converter.tex_export
1import bpy 2import os 3import struct 4from . import common 5from . import compat 6from .translations.pgettext_functions import * 7 8 9@compat.BlRegister() 10class CNV_OT_export_cm3d2_tex(bpy.types.Operator): 11 bl_idname = 'image.export_cm3d2_tex' 12 bl_label = "texファイルを保存" 13 bl_description = "CM3D2で使用されるテクスチャファイル(.tex)として保存します" 14 bl_options = {'REGISTER'} 15 16 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 17 filename_ext = ".tex" 18 filter_glob = bpy.props.StringProperty(default="*.tex", options={'HIDDEN'}) 19 20 is_backup = bpy.props.BoolProperty(name="ファイルをバックアップ", default=True, description="ファイルに上書きする場合にバックアップファイルを複製します") 21 22 version = bpy.props.EnumProperty( 23 name="ファイルバージョン", 24 items=[ 25 ('1011', '1011', 'COM3D2 1.13 or later', 'NONE', 0), 26 ('1010', '1010', 'CM3D2 1.49 ~ or COM3D2', 'NONE', 1), 27 ('1000', '1000', '旧フォーマット', 'NONE', 2), 28 ], default='1010') 29 path = bpy.props.StringProperty(name="パス", default=common.BASE_PATH_TEX + "/*.png") 30 31 @classmethod 32 def poll(cls, context): 33 if hasattr(context, 'edit_image'): 34 img = context.edit_image 35 if img and (len(img.pixels) or img.source == 'VIEWER'): 36 return True 37 return False 38 39 def invoke(self, context, event): 40 prefs = common.preferences() 41 img = context.edit_image 42 if img.filepath: 43 prefs.tex_export_path = bpy.path.abspath(img.filepath) 44 if prefs.tex_default_path: 45 self.filepath = common.default_cm3d2_dir(prefs.tex_default_path, common.remove_serial_number(img.name), "tex") 46 else: 47 self.filepath = common.default_cm3d2_dir(prefs.tex_export_path, common.remove_serial_number(img.name), "tex") 48 self.is_backup = bool(prefs.backup_ext) 49 self.path = img.get('cm3d2_path') 50 if self.path is None: 51 self.path = common.get_tex_cm3d2path(self.filepath) 52 img['cm3d2_path'] = self.path 53 54 if 'tex Name' in img: 55 self.filepath = os.path.join(os.path.dirname(self.filepath), img['tex Name']) 56 context.window_manager.fileselect_add(self) 57 return {'RUNNING_MODAL'} 58 59 def draw(self, context): 60 row = self.layout.row() 61 row.prop(self, 'is_backup', icon='FILE_BACKUP') 62 if not common.preferences().backup_ext: 63 row.enabled = False 64 self.layout.prop(self, 'version', icon='LINENUMBERS_ON') 65 self.layout.prop(self, 'path', icon='ANIM') 66 67 def execute(self, context): 68 common.preferences().tex_export_path = self.filepath 69 70 try: 71 with common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) as file: 72 version_num = int(self.version) 73 self.write_texture(context, file, version_num) 74 self.report(type={'INFO'}, message="texファイルを出力しました。" + self.filepath) 75 76 except common.CM3D2ExportException as e: 77 self.report(type={'ERROR'}, message=str(e)) 78 return {'CANCELLED'} 79 except Exception as e: 80 self.report(type={'ERROR'}, message=f_tip_("texファイルの出力に失敗しました。{}", str(e))) 81 return {'CANCELLED'} 82 83 return {'FINISHED'} 84 85 def write_texture(self, context, file, version): 86 # とりあえずpngで保存 87 img = context.edit_image 88 if img.source != 'VIEWER': 89 temp_path = self.filepath + ".temp.png" 90 else: 91 temp_path = os.path.splitext(self.filepath)[0] + ".png" 92 pre_filepath = bpy.path.abspath(img.filepath) 93 pre_source = img.source 94 override = context.copy() 95 override['edit_image'] = img 96 try: 97 save_as_render = True if pre_source == 'VIEWER' else False 98 copy = True if pre_source == 'VIEWER' else False 99 bpy.ops.image.save_as(override, save_as_render=save_as_render, copy=copy, filepath=temp_path, relative_path=True, show_multiview=False, use_multiview=False) 100 is_remove = True 101 except: 102 temp_path = bpy.path.abspath(img.filepath) 103 if os.path.exists(temp_path): 104 is_remove = False 105 else: 106 raise common.CM3D2ExportException("PNGファイルの取得に失敗しました") 107 if pre_source != 'VIEWER': 108 img.filepath = pre_filepath 109 img.source = pre_source 110 111 # pngバイナリを全て読み込み 112 with open(temp_path, 'rb') as temp_file: 113 temp_data = temp_file.read() 114 # 一時ファイルを削除 115 if is_remove: 116 os.remove(temp_path) 117 118 # 本命ファイルに書き込み 119 common.write_str(file, 'CM3D2_TEX') 120 file.write(struct.pack('<i', version)) 121 common.write_str(file, self.path) 122 if version >= 1010: 123 if version >= 1011: 124 uv_rects = bpy.types.Scene.MyUVRects if hasattr(bpy.types.Scene, 'MyUVRects') else None 125 num_rects = len(uv_rects) if uv_rects else 0 126 file.write(struct.pack('<i', num_rects)) 127 if num_rects > 0: 128 for uv_rect in uv_rects: 129 file.write( struct.pack('<4f', uv_rect[0], uv_rect[1], uv_rect[2], uv_rect[3]) ) 130 131 width, height = img.size 132 file.write(struct.pack('<i', width)) 133 file.write(struct.pack('<i', height)) 134 file.write(struct.pack('<i', 5)) # tex_format TODO ダイアログで指定 135 file.write(struct.pack('<i', len(temp_data))) 136 file.write(temp_data) 137 138 139# メニューを登録する関数 140def menu_func(self, context): 141 self.layout.operator(CNV_OT_export_cm3d2_tex.bl_idname, icon_value=common.kiss_icon())
@compat.BlRegister()
class
CNV_OT_export_cm3d2_tex10@compat.BlRegister() 11class CNV_OT_export_cm3d2_tex(bpy.types.Operator): 12 bl_idname = 'image.export_cm3d2_tex' 13 bl_label = "texファイルを保存" 14 bl_description = "CM3D2で使用されるテクスチャファイル(.tex)として保存します" 15 bl_options = {'REGISTER'} 16 17 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 18 filename_ext = ".tex" 19 filter_glob = bpy.props.StringProperty(default="*.tex", options={'HIDDEN'}) 20 21 is_backup = bpy.props.BoolProperty(name="ファイルをバックアップ", default=True, description="ファイルに上書きする場合にバックアップファイルを複製します") 22 23 version = bpy.props.EnumProperty( 24 name="ファイルバージョン", 25 items=[ 26 ('1011', '1011', 'COM3D2 1.13 or later', 'NONE', 0), 27 ('1010', '1010', 'CM3D2 1.49 ~ or COM3D2', 'NONE', 1), 28 ('1000', '1000', '旧フォーマット', 'NONE', 2), 29 ], default='1010') 30 path = bpy.props.StringProperty(name="パス", default=common.BASE_PATH_TEX + "/*.png") 31 32 @classmethod 33 def poll(cls, context): 34 if hasattr(context, 'edit_image'): 35 img = context.edit_image 36 if img and (len(img.pixels) or img.source == 'VIEWER'): 37 return True 38 return False 39 40 def invoke(self, context, event): 41 prefs = common.preferences() 42 img = context.edit_image 43 if img.filepath: 44 prefs.tex_export_path = bpy.path.abspath(img.filepath) 45 if prefs.tex_default_path: 46 self.filepath = common.default_cm3d2_dir(prefs.tex_default_path, common.remove_serial_number(img.name), "tex") 47 else: 48 self.filepath = common.default_cm3d2_dir(prefs.tex_export_path, common.remove_serial_number(img.name), "tex") 49 self.is_backup = bool(prefs.backup_ext) 50 self.path = img.get('cm3d2_path') 51 if self.path is None: 52 self.path = common.get_tex_cm3d2path(self.filepath) 53 img['cm3d2_path'] = self.path 54 55 if 'tex Name' in img: 56 self.filepath = os.path.join(os.path.dirname(self.filepath), img['tex Name']) 57 context.window_manager.fileselect_add(self) 58 return {'RUNNING_MODAL'} 59 60 def draw(self, context): 61 row = self.layout.row() 62 row.prop(self, 'is_backup', icon='FILE_BACKUP') 63 if not common.preferences().backup_ext: 64 row.enabled = False 65 self.layout.prop(self, 'version', icon='LINENUMBERS_ON') 66 self.layout.prop(self, 'path', icon='ANIM') 67 68 def execute(self, context): 69 common.preferences().tex_export_path = self.filepath 70 71 try: 72 with common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) as file: 73 version_num = int(self.version) 74 self.write_texture(context, file, version_num) 75 self.report(type={'INFO'}, message="texファイルを出力しました。" + self.filepath) 76 77 except common.CM3D2ExportException as e: 78 self.report(type={'ERROR'}, message=str(e)) 79 return {'CANCELLED'} 80 except Exception as e: 81 self.report(type={'ERROR'}, message=f_tip_("texファイルの出力に失敗しました。{}", str(e))) 82 return {'CANCELLED'} 83 84 return {'FINISHED'} 85 86 def write_texture(self, context, file, version): 87 # とりあえずpngで保存 88 img = context.edit_image 89 if img.source != 'VIEWER': 90 temp_path = self.filepath + ".temp.png" 91 else: 92 temp_path = os.path.splitext(self.filepath)[0] + ".png" 93 pre_filepath = bpy.path.abspath(img.filepath) 94 pre_source = img.source 95 override = context.copy() 96 override['edit_image'] = img 97 try: 98 save_as_render = True if pre_source == 'VIEWER' else False 99 copy = True if pre_source == 'VIEWER' else False 100 bpy.ops.image.save_as(override, save_as_render=save_as_render, copy=copy, filepath=temp_path, relative_path=True, show_multiview=False, use_multiview=False) 101 is_remove = True 102 except: 103 temp_path = bpy.path.abspath(img.filepath) 104 if os.path.exists(temp_path): 105 is_remove = False 106 else: 107 raise common.CM3D2ExportException("PNGファイルの取得に失敗しました") 108 if pre_source != 'VIEWER': 109 img.filepath = pre_filepath 110 img.source = pre_source 111 112 # pngバイナリを全て読み込み 113 with open(temp_path, 'rb') as temp_file: 114 temp_data = temp_file.read() 115 # 一時ファイルを削除 116 if is_remove: 117 os.remove(temp_path) 118 119 # 本命ファイルに書き込み 120 common.write_str(file, 'CM3D2_TEX') 121 file.write(struct.pack('<i', version)) 122 common.write_str(file, self.path) 123 if version >= 1010: 124 if version >= 1011: 125 uv_rects = bpy.types.Scene.MyUVRects if hasattr(bpy.types.Scene, 'MyUVRects') else None 126 num_rects = len(uv_rects) if uv_rects else 0 127 file.write(struct.pack('<i', num_rects)) 128 if num_rects > 0: 129 for uv_rect in uv_rects: 130 file.write( struct.pack('<4f', uv_rect[0], uv_rect[1], uv_rect[2], uv_rect[3]) ) 131 132 width, height = img.size 133 file.write(struct.pack('<i', width)) 134 file.write(struct.pack('<i', height)) 135 file.write(struct.pack('<i', 5)) # tex_format TODO ダイアログで指定 136 file.write(struct.pack('<i', len(temp_data))) 137 file.write(temp_data)
filepath: <_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}>
filter_glob: <_PropertyDeferred, <built-in function StringProperty>, {'default': '*.tex', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'default': '*.tex', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}>
is_backup: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'ファイルをバックアップ', 'default': True, 'description': 'ファイルに上書きする場合にバックアップファイルを複製します', 'attr': 'is_backup'}> =
<_PropertyDeferred, <built-in function BoolProperty>, {'name': 'ファイルをバックアップ', 'default': True, 'description': 'ファイルに上書きする場合にバックアップファイルを複製します', 'attr': 'is_backup'}>
version: <_PropertyDeferred, <built-in function EnumProperty>, {'name': 'ファイルバージョン', 'items': [('1011', '1011', 'COM3D2 1.13 or later', 'NONE', 0), ('1010', '1010', 'CM3D2 1.49 ~ or COM3D2', 'NONE', 1), ('1000', '1000', '旧フォーマット', 'NONE', 2)], 'default': '1010', 'attr': 'version'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'name': 'ファイルバージョン', 'items': [('1011', '1011', 'COM3D2 1.13 or later', 'NONE', 0), ('1010', '1010', 'CM3D2 1.49 ~ or COM3D2', 'NONE', 1), ('1000', '1000', '旧フォーマット', 'NONE', 2)], 'default': '1010', 'attr': 'version'}>
path: <_PropertyDeferred, <built-in function StringProperty>, {'name': 'パス', 'default': 'Assets/texture/texture//*.png', 'attr': 'path'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'name': 'パス', 'default': 'Assets/texture/texture//*.png', 'attr': 'path'}>
def
invoke(self, context, event):
40 def invoke(self, context, event): 41 prefs = common.preferences() 42 img = context.edit_image 43 if img.filepath: 44 prefs.tex_export_path = bpy.path.abspath(img.filepath) 45 if prefs.tex_default_path: 46 self.filepath = common.default_cm3d2_dir(prefs.tex_default_path, common.remove_serial_number(img.name), "tex") 47 else: 48 self.filepath = common.default_cm3d2_dir(prefs.tex_export_path, common.remove_serial_number(img.name), "tex") 49 self.is_backup = bool(prefs.backup_ext) 50 self.path = img.get('cm3d2_path') 51 if self.path is None: 52 self.path = common.get_tex_cm3d2path(self.filepath) 53 img['cm3d2_path'] = self.path 54 55 if 'tex Name' in img: 56 self.filepath = os.path.join(os.path.dirname(self.filepath), img['tex Name']) 57 context.window_manager.fileselect_add(self) 58 return {'RUNNING_MODAL'}
def
execute(self, context):
68 def execute(self, context): 69 common.preferences().tex_export_path = self.filepath 70 71 try: 72 with common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) as file: 73 version_num = int(self.version) 74 self.write_texture(context, file, version_num) 75 self.report(type={'INFO'}, message="texファイルを出力しました。" + self.filepath) 76 77 except common.CM3D2ExportException as e: 78 self.report(type={'ERROR'}, message=str(e)) 79 return {'CANCELLED'} 80 except Exception as e: 81 self.report(type={'ERROR'}, message=f_tip_("texファイルの出力に失敗しました。{}", str(e))) 82 return {'CANCELLED'} 83 84 return {'FINISHED'}
def
write_texture(self, context, file, version):
86 def write_texture(self, context, file, version): 87 # とりあえずpngで保存 88 img = context.edit_image 89 if img.source != 'VIEWER': 90 temp_path = self.filepath + ".temp.png" 91 else: 92 temp_path = os.path.splitext(self.filepath)[0] + ".png" 93 pre_filepath = bpy.path.abspath(img.filepath) 94 pre_source = img.source 95 override = context.copy() 96 override['edit_image'] = img 97 try: 98 save_as_render = True if pre_source == 'VIEWER' else False 99 copy = True if pre_source == 'VIEWER' else False 100 bpy.ops.image.save_as(override, save_as_render=save_as_render, copy=copy, filepath=temp_path, relative_path=True, show_multiview=False, use_multiview=False) 101 is_remove = True 102 except: 103 temp_path = bpy.path.abspath(img.filepath) 104 if os.path.exists(temp_path): 105 is_remove = False 106 else: 107 raise common.CM3D2ExportException("PNGファイルの取得に失敗しました") 108 if pre_source != 'VIEWER': 109 img.filepath = pre_filepath 110 img.source = pre_source 111 112 # pngバイナリを全て読み込み 113 with open(temp_path, 'rb') as temp_file: 114 temp_data = temp_file.read() 115 # 一時ファイルを削除 116 if is_remove: 117 os.remove(temp_path) 118 119 # 本命ファイルに書き込み 120 common.write_str(file, 'CM3D2_TEX') 121 file.write(struct.pack('<i', version)) 122 common.write_str(file, self.path) 123 if version >= 1010: 124 if version >= 1011: 125 uv_rects = bpy.types.Scene.MyUVRects if hasattr(bpy.types.Scene, 'MyUVRects') else None 126 num_rects = len(uv_rects) if uv_rects else 0 127 file.write(struct.pack('<i', num_rects)) 128 if num_rects > 0: 129 for uv_rect in uv_rects: 130 file.write( struct.pack('<4f', uv_rect[0], uv_rect[1], uv_rect[2], uv_rect[3]) ) 131 132 width, height = img.size 133 file.write(struct.pack('<i', width)) 134 file.write(struct.pack('<i', height)) 135 file.write(struct.pack('<i', 5)) # tex_format TODO ダイアログで指定 136 file.write(struct.pack('<i', len(temp_data))) 137 file.write(temp_data)
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data